/*
 * Copyright (c) 2009-2024 Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*============================ INCLUDES ======================================*/
#if 1
#if defined(_RTE_)
#   include "RTE_Components.h"
#endif

#if defined(RTE_Acceleration_Arm_2D_Helper_PFB)

#include "arm_2d.h"

#ifdef RTE_Acceleration_Arm_2D_Scene2

#define __USER_SCENE2_IMPLEMENT__
#include "arm_2d_scene_2.h"
#include "arm_2d_scenes.h"
#include "arm_2d_helper.h"
#include "arm_2d_example_controls.h"

#include <stdlib.h>
#include <string.h>

#if defined(__clang__)
#   pragma clang diagnostic push
#   pragma clang diagnostic ignored "-Wunknown-warning-option"
#   pragma clang diagnostic ignored "-Wreserved-identifier"
#   pragma clang diagnostic ignored "-Wsign-conversion"
#   pragma clang diagnostic ignored "-Wpadded"
#   pragma clang diagnostic ignored "-Wcast-qual"
#   pragma clang diagnostic ignored "-Wcast-align"
#   pragma clang diagnostic ignored "-Wmissing-field-initializers"
#   pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#   pragma clang diagnostic ignored "-Wmissing-prototypes"
#   pragma clang diagnostic ignored "-Wunused-variable"
#   pragma clang diagnostic ignored "-Wgnu-statement-expression"
#   pragma clang diagnostic ignored "-Wdeclaration-after-statement"
#   pragma clang diagnostic ignored "-Wunused-function"
#   pragma clang diagnostic ignored "-Wmissing-declarations"  
#elif __IS_COMPILER_ARM_COMPILER_5__
#   pragma diag_suppress 64,177
#elif __IS_COMPILER_IAR__
#   pragma diag_suppress=Pa089,Pe188,Pe177,Pe174
#elif __IS_COMPILER_GCC__
#   pragma GCC diagnostic push
#   pragma GCC diagnostic ignored "-Wformat="
#   pragma GCC diagnostic ignored "-Wpedantic"
#   pragma GCC diagnostic ignored "-Wunused-function"
#   pragma GCC diagnostic ignored "-Wunused-variable"
#   pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
#endif

/*============================ MACROS ========================================*/

#if __GLCD_CFG_COLOUR_DEPTH__ == 8

#   define c_tileCMSISLogo          c_tileCMSISLogoGRAY8

#elif __GLCD_CFG_COLOUR_DEPTH__ == 16

#   define c_tileCMSISLogo          c_tileCMSISLogoRGB565

#elif __GLCD_CFG_COLOUR_DEPTH__ == 32

#   define c_tileCMSISLogo          c_tileCMSISLogoCCCA8888
#else
#   error Unsupported colour depth!
#endif

/*============================ MACROFIED FUNCTIONS ===========================*/
#undef this
#define this (*ptThis)

/*============================ TYPES =========================================*/
/*============================ GLOBAL VARIABLES ==============================*/
char Tetris_go_back_flag = 0;

void Tetris_init();
void Tetris_level_run();
void Tetris_run();
void draw_my_Tetris(void *pTarget,                                  
                 const arm_2d_tile_t *ptTile,                   
                 bool bIsNewFrame);

/*============================ PROTOTYPES ====================================*/
/*============================ LOCAL VARIABLES ===============================*/

/*! define dirty regions */
IMPL_ARM_2D_REGION_LIST(s_tDirtyRegions, static)

    /* a dirty region to be specified at runtime*/
    ADD_REGION_TO_LIST(s_tDirtyRegions,
        0  /* initialize at runtime later */
    ),
    
    /* add the last region:
        * it is the top left corner for text display 
        */
    ADD_LAST_REGION_TO_LIST(s_tDirtyRegions,
        .tLocation = {
            .iX = 0,
            .iY = 0,
        },
        .tSize = {
            .iWidth = 320,
            .iHeight = 240,
        },
    ),

END_IMPL_ARM_2D_REGION_LIST(s_tDirtyRegions)

/*============================ IMPLEMENTATION ================================*/

static void __on_scene2_load(arm_2d_scene_t *ptScene)
{
    user_scene_2_t *ptThis = (user_scene_2_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}

static void __on_scene2_depose(arm_2d_scene_t *ptScene)
{
    user_scene_2_t *ptThis = (user_scene_2_t *)ptScene;
    ARM_2D_UNUSED(ptThis);
    
    ptScene->ptPlayer = NULL;
    
    /* reset timestamp */
    arm_foreach(int64_t,this.lTimestamp, ptItem) {
        *ptItem = 0;
    }

    if (!this.bUserAllocated) {
        __arm_2d_free_scratch_memory(ARM_2D_MEM_TYPE_UNSPECIFIED, ptScene);
    }
}

/*----------------------------------------------------------------------------*
 * Scene 2                                                                    *
 *----------------------------------------------------------------------------*/

static void __on_scene2_background_start(arm_2d_scene_t *ptScene)
{
    user_scene_2_t *ptThis = (user_scene_2_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}

static void __on_scene2_background_complete(arm_2d_scene_t *ptScene)
{
    user_scene_2_t *ptThis = (user_scene_2_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}


static void __on_scene2_frame_start(arm_2d_scene_t *ptScene)
{
    user_scene_2_t *ptThis = (user_scene_2_t *)ptScene;
    ARM_2D_UNUSED(ptThis);
		//Tetris_run();
	   /* switch to next scene after 3s */
    if (arm_2d_helper_is_time_out(500, &this.lTimestamp[0])) {
       
			  Tetris_level_run();
    }
		Tetris_run();
		

}

static void __on_scene2_frame_complete(arm_2d_scene_t *ptScene)
{
    user_scene_2_t *ptThis = (user_scene_2_t *)ptScene;
    ARM_2D_UNUSED(ptThis);
    if(Tetris_go_back_flag){
				Tetris_go_back_flag = 0;
				__arm_2d_scene1_init(   &DISP0_ADAPTER ,NULL);
				arm_2d_scene_player_switch_to_next_scene(ptScene->ptPlayer);
		}
   
}

static void __before_scene2_switching_out(arm_2d_scene_t *ptScene)
{
    user_scene_2_t *ptThis = (user_scene_2_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}
 uint8_t temp1 = 0;
uint8_t temp2 = 0;
uint8_t temp3 = 0;
uint8_t temp4 = 0;
static
IMPL_PFB_ON_DRAW(__pfb_draw_scene2_handler)
{
    user_scene_2_t *ptThis = (user_scene_2_t *)pTarget;
    arm_2d_size_t tScreenSize = ptTile->tRegion.tSize;

    ARM_2D_UNUSED(ptTile);
    ARM_2D_UNUSED(bIsNewFrame);
    ARM_2D_UNUSED(tScreenSize);
    
    arm_2d_canvas(ptTile, __top_canvas) {
    /*-----------------------draw the foreground begin-----------------------*/
        
        /* following code is just a demo, you can remove them */
        
        arm_2d_fill_colour(ptTile, NULL, GLCD_COLOR_WHITE);

        draw_my_Tetris(pTarget,                                  
                 ptTile,                   
                  bIsNewFrame);


   

        /* draw text at the top-left corner */

        arm_lcd_text_set_target_framebuffer((arm_2d_tile_t *)ptTile);
        arm_lcd_text_set_font(&ARM_2D_FONT_6x8.use_as__arm_2d_font_t);
        arm_lcd_text_set_draw_region(NULL);
        arm_lcd_text_set_colour(GLCD_COLOR_RED, GLCD_COLOR_WHITE);
        arm_lcd_text_location(0,0);
        arm_lcd_printf("Scene 2=%d=%d=%d=%d",temp1,temp2,temp3,temp4);

    /*-----------------------draw the foreground end  -----------------------*/
    }
    arm_2d_op_wait_async(NULL);

    return arm_fsm_rt_cpl;
}

ARM_NONNULL(1)
user_scene_2_t *__arm_2d_scene2_init(   arm_2d_scene_player_t *ptDispAdapter, 
                                        user_scene_2_t *ptThis)
{
    bool bUserAllocated = false;
    assert(NULL != ptDispAdapter);

    s_tDirtyRegions[dimof(s_tDirtyRegions)-1].ptNext = NULL;

    /* get the screen region */
    arm_2d_region_t tScreen
        = arm_2d_helper_pfb_get_display_area(
            &ptDispAdapter->use_as__arm_2d_helper_pfb_t);

    /* initialise dirty region 0 at runtime
     * this demo shows that we create a region in the centre of a screen(320*240)
     * for a image stored in the tile c_tileCMSISLogoMask
     */
    //arm_2d_align_centre(tScreen, c_tileCMSISLogoMask.tRegion.tSize) {
        //s_tDirtyRegions[0].tRegion = __centre_region;
    //}

    //s_tDirtyRegions[dimof(s_tDirtyRegions)-1].tRegion.tSize.iWidth 
    //                                                    = tScreen.tSize.iWidth;
    
    if (NULL == ptThis) {
        ptThis = (user_scene_2_t *)
                    __arm_2d_allocate_scratch_memory(   sizeof(user_scene_2_t),
                                                        __alignof__(user_scene_2_t),
                                                        ARM_2D_MEM_TYPE_UNSPECIFIED);
        assert(NULL != ptThis);
        if (NULL == ptThis) {
            return NULL;
        }
    } else {
        bUserAllocated = true;
    }
    memset(ptThis, 0, sizeof(user_scene_2_t));

    *ptThis = (user_scene_2_t){
        .use_as__arm_2d_scene_t = {

            /* the canvas colour */
            .tCanvas = {GLCD_COLOR_WHITE}, 

            /* Please uncommon the callbacks if you need them
             */
            .fnOnLoad       = &__on_scene2_load,
            .fnScene        = &__pfb_draw_scene2_handler,
            .ptDirtyRegion  = (arm_2d_region_list_item_t *)s_tDirtyRegions,
            

            //.fnOnBGStart    = &__on_scene2_background_start,
            //.fnOnBGComplete = &__on_scene2_background_complete,
            .fnOnFrameStart = &__on_scene2_frame_start,
            //.fnBeforeSwitchOut = &__before_scene2_switching_out,
            .fnOnFrameCPL   = &__on_scene2_frame_complete,
            .fnDepose       = &__on_scene2_depose,

            .bUseDirtyRegionHelper = false,
        },
        .bUserAllocated = bUserAllocated,
    };

    /* ------------   initialize members of user_scene_2_t begin ---------------*/


    /* ------------   initialize members of user_scene_2_t end   ---------------*/

    arm_2d_scene_player_append_scenes(  ptDispAdapter, 
                                        &this.use_as__arm_2d_scene_t, 
                                        1);

		Tetris_init();																		
    return ptThis;
}
//===========================================================
//===========================================================================================

const uint16_t Tetris_move_bodys[7][4]= {
		{0x00e4,0x0464,0x004e,0x0262},//T
		{0x4444,0x000f,0x2222,0x000f},//I
		{0x088c,0x002e,0x0c44,0x00e8},//L
		{0x044c,0x00e2,0x0c88,0x008e},//J
		{0x00c6,0x04c8,0x00c6,0x04c8},//Z
		{0x006c,0x08c4,0x006c,0x08c4},//5 
		{0x0066,0x0066,0x0066,0x0066},//O 
		//{0x0000,0x0000,0x0000,0x0000},// 

};

extern uint16_t key_num ;
#define Tetris_WIDTH  10
#define Tetris_HEIGHT  20

#define Location_iX_init 10
#define Location_iY_init 20

struct {
		uint8_t Tetris_datas[Tetris_HEIGHT ][Tetris_WIDTH];
		uint8_t Tetris_move_body[4][4];
		uint8_t Tetris_bottom_datas[Tetris_WIDTH];
		uint8_t Tetris_move_body_bottom_datas[4];
			
		uint16_t radom_hang;
	  uint16_t radom_lie;
	
	  uint8_t block_width;//10
		char move_body_hang;
		char move_body_lie;
		int16_t block_iX;
	  int16_t block_iY;
	  char move_max_iY;
		char move_max_left;
		char move_max_right;
	
	  char game_over_flag;
}my_Tetris;

void draw_my_block_box(void *pTarget,                                  
                 const arm_2d_tile_t *ptTile, 
								arm_2d_region_t Region,				
                 bool bIsNewFrame){
    arm_2d_region_t myRegion;	
		myRegion.tLocation.iX = Region.tLocation.iX;
		myRegion.tLocation.iY	 = Region.tLocation.iY -3;
		myRegion.tSize.iHeight = 3;
		myRegion.tSize.iWidth = Region.tSize.iWidth;	

	  arm_2d_fill_colour_with_opacity(   
                ptTile, 
                &myRegion, 
                (__arm_2d_color_t){GLCD_COLOR_BLACK},
                100);
								
		myRegion.tLocation.iY	 = Region.tLocation.iY + Region.tSize.iHeight;
		arm_2d_fill_colour_with_opacity(   
                ptTile, 
                &myRegion, 
                (__arm_2d_color_t){GLCD_COLOR_BLACK},
                100);	

		myRegion.tLocation.iX = Region.tLocation.iX-3;
		myRegion.tLocation.iY	 = Region.tLocation.iY -3;
		myRegion.tSize.iHeight = Region.tSize.iHeight +6;
		myRegion.tSize.iWidth = 3;	
		arm_2d_fill_colour_with_opacity(   
                ptTile, 
                &myRegion, 
                (__arm_2d_color_t){GLCD_COLOR_BLACK},
                100);	
								
		myRegion.tLocation.iX = Region.tLocation.iX + Region.tSize.iWidth;		
		arm_2d_fill_colour_with_opacity(   
                ptTile, 
                &myRegion, 
                (__arm_2d_color_t){GLCD_COLOR_BLACK},
                100);								
								
}

void draw_my_Tetris(void *pTarget,                                  
                 const arm_2d_tile_t *ptTile,                   
                 bool bIsNewFrame){
									 
		char i,j;
		arm_2d_region_t myRegion;
									 
		do{					 
		    myRegion.tLocation.iX = Location_iX_init;
		    myRegion.tLocation.iY	 = Location_iY_init;
		    myRegion.tSize.iHeight = my_Tetris.block_width;
		    myRegion.tSize.iWidth = my_Tetris.block_width;								 
				for(i = 0; i <  Tetris_HEIGHT ; i++){				
						myRegion.tLocation.iY	 = Location_iY_init + i * my_Tetris.block_width;
						for(j = 0; j < Tetris_WIDTH;j++){						
								if(my_Tetris.Tetris_datas[i][j]){
										myRegion.tLocation.iX = Location_iX_init + j * my_Tetris.block_width;
										draw_round_corner_box(  ptTile, 
																&myRegion, 
																GLCD_COLOR_BLACK, 
																255,
																bIsNewFrame);
								}
						}
				}

		    myRegion.tLocation.iX = Location_iX_init;
		    myRegion.tLocation.iY	 = Location_iY_init;
				myRegion.tSize.iHeight =  Tetris_HEIGHT * my_Tetris.block_width;
				myRegion.tSize.iWidth = Tetris_WIDTH * my_Tetris.block_width;	
				draw_my_block_box(pTarget,                                  
										 ptTile, 
										 myRegion,				
											bIsNewFrame)	;
	  }while(0);
		
		do{
			uint16_t iX = Location_iX_init + my_Tetris.block_width + Tetris_WIDTH * my_Tetris.block_width ;
				myRegion.tLocation.iX = Location_iX_init + my_Tetris.block_width + Tetris_WIDTH * my_Tetris.block_width;
				myRegion.tLocation.iY	 = Location_iY_init ;
				myRegion.tSize.iHeight =  4 * my_Tetris.block_width;
				myRegion.tSize.iWidth = 4 * my_Tetris.block_width;	
			  draw_my_block_box(pTarget,                                  
                 ptTile, 
								 myRegion,				
                  bIsNewFrame)	;
			
			  myRegion.tSize.iHeight = my_Tetris.block_width;
		    myRegion.tSize.iWidth = my_Tetris.block_width;
				for(i = 0; i < 4; i++){
						
						myRegion.tLocation.iY	 = Location_iY_init + i * my_Tetris.block_width;
						for(j = 0; j < 4;j++){
								myRegion.tLocation.iX = iX + j * my_Tetris.block_width;
								if(my_Tetris.Tetris_move_body[i][j]){
										draw_round_corner_box(  ptTile, 
																&myRegion, 
																GLCD_COLOR_BLACK, 
																255,
																bIsNewFrame);
								}
						}
				}
		}while(0);
		do{
			  int16_t iY = Location_iY_init + my_Tetris.block_iY * my_Tetris.block_width ;
			  int16_t iX  = Location_iX_init + (my_Tetris.block_iX * my_Tetris.block_width) ;
			  
				//iX = Location_iX_init + (my_Tetris.block_iX * my_Tetris.block_width) ;
		    myRegion.tSize.iHeight = my_Tetris.block_width;
		    myRegion.tSize.iWidth = my_Tetris.block_width;
				for(i = 0; i < 4; i++){
						
						myRegion.tLocation.iY	 = iY + i * my_Tetris.block_width;
						for(j = 0; j < 4;j++){								
								if(my_Tetris.Tetris_move_body[i][j]){
									  
									  myRegion.tLocation.iX = iX + j * my_Tetris.block_width;
										draw_round_corner_box(  ptTile, 
																&myRegion, 
																GLCD_COLOR_BLACK, 
																255,
																bIsNewFrame);
								}
						}
				}
		
		}while(0);
		do{
			  int16_t iY = Location_iY_init + my_Tetris.move_max_iY * my_Tetris.block_width ;
			  int16_t iX = Location_iX_init + my_Tetris.block_iX * my_Tetris.block_width ;
		    myRegion.tSize.iHeight = my_Tetris.block_width;
		    myRegion.tSize.iWidth = my_Tetris.block_width;
				for(i = 0; i < 4; i++){
						
						myRegion.tLocation.iY	 = iY + i * my_Tetris.block_width;
						for(j = 0; j < 4;j++){								
								if(my_Tetris.Tetris_move_body[i][j]){
									  myRegion.tLocation.iX = iX + j * my_Tetris.block_width;
										draw_round_corner_box(  ptTile, 
																&myRegion, 
																GLCD_COLOR_GREEN, 
																55,
																bIsNewFrame);
								}
						}
				}
		
		}while(0);
		do{
		    if(my_Tetris.game_over_flag){
				    arm_lcd_text_set_target_framebuffer((arm_2d_tile_t *)ptTile);
						arm_lcd_text_set_font(&ARM_2D_FONT_16x24.use_as__arm_2d_font_t);
						arm_lcd_text_set_draw_region(NULL);
					
					
						
						arm_lcd_text_set_colour(GLCD_COLOR_RED, GLCD_COLOR_WHITE);
						arm_lcd_text_location(3,4);
						
						arm_lcd_printf("Game Over!!");
					
				}
		
		}while(0);
									 
}
//=================================================	
void Tetris_add_move_body();
void Tetris_calculate_body_bottom_datas();
void Tetris_init(){
		char i,j;
		for(i = 0; i < Tetris_HEIGHT ; i++){
				for(j = 0; j < Tetris_WIDTH;j++){
						my_Tetris.Tetris_datas[i][j] = 0;
				}
		}		
		
		my_Tetris.block_width = 10;		
		my_Tetris.move_max_iY = Tetris_HEIGHT - 4; 
		my_Tetris.game_over_flag = 0;
		
		Tetris_add_move_body();
}

void Tetris_add_radom_block(){
	  my_Tetris.block_iX = 3;
		my_Tetris.block_iY = 0;
		my_Tetris.move_body_hang = my_Tetris.radom_hang % 7;
		my_Tetris.move_body_lie = my_Tetris.radom_lie & 0x03;
}

void Tetris_change_block(){
	  char i,j;
	  uint16_t data ;
	  uint8_t temp = 0;
	  data = Tetris_move_bodys[my_Tetris.move_body_hang][my_Tetris.move_body_lie];
    for(i = 0; i < 4; i++){
				
				for( j = 0; j < 4; j++){
						my_Tetris.Tetris_move_body[i][j] = 0;
				}
		}
		for(i = 0; i < 4; i++){
				if(i == 0){
						temp = (data >> 12) & 0x0f;
						//temp1 = temp;
				}
				else if(i == 1){
						temp = (data >> 8) & 0x0f;
						//temp2 = temp;
				}
				else if(i == 2){
						temp = (data >> 4) & 0x0f;
						//temp3 = temp;
				}else if(i == 3){
						temp = data & 0x0f;
					  //temp4 = temp;
				}
				for( j = 0; j < 4; j++){
						if(temp & 0x08){
								my_Tetris.Tetris_move_body[i][j] = 1;
						}
						temp = temp<<1;
				}
		}
		Tetris_calculate_body_bottom_datas();	
}
void Tetris_add_move_body(){	
	  Tetris_add_radom_block();
	  Tetris_change_block();
    
}


void Tetris_calculate_body_bottom_datas(){
    char i,j;
		for(i = 0; i < 4; i++ ){
			  my_Tetris.Tetris_move_body_bottom_datas[i] = 0;
		    for(j = 0; j < 4; j++){
					  if(my_Tetris.Tetris_move_body[3-j][i]){
								my_Tetris.Tetris_move_body_bottom_datas[i] = 3-j;
							  break;
								//continue;
						}

				}					
		}
		for(i = 0; i < 4; i++ ){
				if(my_Tetris.Tetris_move_body_bottom_datas[i]){
							my_Tetris.move_max_left = i;
						break;
				}
		}
		for(i = 0; i < 4; i++ ){
				if(my_Tetris.Tetris_move_body_bottom_datas[3-i]){
							my_Tetris.move_max_right = i;
						break;
				}
		}
		
}

char Tetris_get_is_move_up_flag(){
    char i,j,flag;
	  flag = 0;

    if( (my_Tetris.block_iX + my_Tetris.move_max_left) < 0){
		    
			  flag = 1;
		}
		if( my_Tetris.block_iX > (Tetris_WIDTH - 4 + my_Tetris.move_max_right)){
		    
			  flag = 1;
		}
		
		for(i = 0; i < 4; i++){
		    for(j = 0; j < 4; j++){
						if(my_Tetris.Tetris_move_body[i][j] ){
							  if(((j + my_Tetris.block_iX) >= Tetris_WIDTH)  || ((j + my_Tetris.block_iX) < 0)){
								    continue;
								}
		            if(my_Tetris.Tetris_datas[i + my_Tetris.block_iY][j + my_Tetris.block_iX]){
								    flag = 1;
								}
						}
				}
		}
    return 	flag;
}

void Tetris_block_move_left(){
    char i,j,flag;
	  flag = 0;
    my_Tetris.block_iX--;
	  
		flag = Tetris_get_is_move_up_flag();
		if(flag){
		    my_Tetris.block_iX++;
		}
	  
}

void Tetris_block_move_right(){
	  char i,j,flag;
	  flag = 0;
    my_Tetris.block_iX++;
	
	  
		flag = Tetris_get_is_move_up_flag();
		if(flag){
		    my_Tetris.block_iX--;
		}
	
}



void Tetris_block_move_up(){
	  char i,j,flag;
	  flag = 0;
		my_Tetris.move_body_lie++;
		my_Tetris.move_body_lie = my_Tetris.move_body_lie &0x03;
		Tetris_change_block();
	
	  flag = Tetris_get_is_move_up_flag();
		if(flag){
				if(my_Tetris.move_body_lie == 0){
				    my_Tetris.move_body_lie = 3;
				}else{
		        my_Tetris.move_body_lie--;
		    }
				Tetris_change_block();
		}
		
}


void copy_move_body_to_datas(){
		char i,j;
	  for(i = 0; i < 4; i++){
		    for(j = 0; j < 4; j++){
						if(my_Tetris.Tetris_move_body[i][j]){
						    my_Tetris.Tetris_datas[i+ my_Tetris.block_iY][j + my_Tetris.block_iX] = my_Tetris.Tetris_move_body[i][j];
						}
				}
		}
}
char Tetris_get_is_move_down_flag(int16_t yy){
	  char i,j,flag;
	  flag = 0;
    if(yy > 16){
		    flag = 1;
		}
	  for(i = 0; i < 4; i++){
		    for(j = 0; j < 4; j++){
						if(my_Tetris.Tetris_move_body[i][j] ){
							  if(((j + my_Tetris.block_iX) >= Tetris_WIDTH)  || ((j + my_Tetris.block_iX) < 0)){
								    continue;
								}
		            if(my_Tetris.Tetris_datas[i + yy][j + my_Tetris.block_iX]){
								    flag = 1;
								}
						}
				}
		}
		return flag;
}

void Tetris_calculate_move_max_iy(){
	  char i;

	  for( i = 1; i < (Tetris_HEIGHT) ; i++){
		    if( Tetris_get_is_move_down_flag(i)){
				    my_Tetris.move_max_iY = i - 1;
					  break;
				}
		}
    	
}

void Tetris_copy_up_datas(char num){
    char i,j;
	  char layer;
	  layer = num+ my_Tetris.block_iY;
	  for(i = 0; i < Tetris_WIDTH; i++ ){
				my_Tetris.Tetris_datas[layer][i] = 0;
		}
		for(i = 0; i < layer; i++){
		   for( j = 0; j < Tetris_WIDTH; j++){
			   my_Tetris.Tetris_datas[layer-i][j] = my_Tetris.Tetris_datas[layer-i-1][j];
			 }
		}
}

void Tetris_clear_layer(){
    char i,j;
	  char flag = 0;
	  for(i = 0; i < 4; i++){
		    for( j = 0; j < Tetris_WIDTH; j++){
				   if(my_Tetris.Tetris_datas[i+ my_Tetris.block_iY][j] == 0){
						  flag = 0;
							break;
					 }
					 flag = 1;
				}
				if(flag){
				    Tetris_copy_up_datas(i);
				}
		}
}

void Tetris_block_down(){
	  char i,j,flag;
	  flag = 0;
    my_Tetris.block_iY++;
	  
	  flag =  Tetris_get_is_move_down_flag(my_Tetris.block_iY);
		if(flag){
			  my_Tetris.block_iY--;
		    copy_move_body_to_datas();
			  Tetris_clear_layer();
			
			  Tetris_add_move_body();
			  Tetris_calculate_move_max_iy();
			
			  
		}
}

void Tetris_farst_down(){
    my_Tetris.block_iY = my_Tetris.move_max_iY;
	  
	  copy_move_body_to_datas();
			  Tetris_clear_layer();
			
			  Tetris_add_move_body();
			  Tetris_calculate_move_max_iy();
}


void Tetris_keyboard_run(){
		switch(key_num){
			  case 13://zuo yi
					 
					  Tetris_block_move_left();
						Tetris_calculate_move_max_iy();
		    break;
				case 16://you yi
					  Tetris_block_move_right();	
            Tetris_calculate_move_max_iy();				
		    break;
		    case 17:
						Tetris_block_move_up();
				    Tetris_calculate_move_max_iy();
		    break;
				case 20:
						Tetris_farst_down();
				break;
				case 10://返回主页
					 Tetris_go_back_flag = 1;
			  break;
		}
		key_num = 0;
}
void Tetris_game_over(){
	  if(my_Tetris.move_max_iY == 0){
        my_Tetris.game_over_flag = 1;
		}
}
void Tetris_level_run(){
		Tetris_block_down();
	  Tetris_game_over();
}
void Tetris_run(){
		my_Tetris.radom_hang+=1;
		my_Tetris.radom_lie += 3;
		Tetris_keyboard_run();
		//copy_block_to_data();

}


#if defined(__clang__)
#   pragma clang diagnostic pop
#endif

#endif

#endif
#endif
